home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / batchut / strings2.zip / STRINGS.DOC < prev    next >
Encoding:
Text File  |  1992-11-25  |  47.8 KB  |  1,080 lines

  1. STRINGS.COM  (Version 2.0)        Copyright (c) 1991, 1992 Douglas Boling
  2. -------------------------------------------------------------------------
  3.               First Published in PC Magazine December 22, 1992 (Utilities)
  4. -------------------------------------------------------------------------
  5.  
  6. STRINGS:
  7.  
  8.         The original STRINGS.COM removed the restrictions imposed by the DOS
  9. batch file language to give your batch files more versatility. This upgraded
  10. TSR version enhances a number of the original functions and implements more
  11. than 35 new ones.
  12.  
  13.  
  14. Batch Files Get Even Better With Our STRINGS 2.0
  15.  
  16. BY DOUGLAS BOLING
  17.  
  18.     The new version contains not only the batch file commands of the
  19. original utility, but 6 enhanced functions and 35 new ones as well.
  20. In all, as shown in Figure 1 (below) STRINGS now adds about 70 commands
  21. to the batch file language. (Some of these commands can be used from
  22. the DOS prompt as well.) Where the original STRINGS let you add a series
  23. of numbers, read a line from a file, or ask a user a question,
  24. STRINGS 2.0 includes additional functions that allow batch files to
  25. query the date and time, get the current country and codepage, and even
  26. read and write to memory locations.
  27.  
  28.      Perhaps the outstanding new feature of STRINGS 2.0 is that under
  29. DOS 3.3 or later it can now act as an extension to the DOS command
  30. processor, COMMAND.COM.  This required rewriting the program so it could
  31. become a TSR.
  32.  
  33.      Once memory resident, since COMMAND.COM no longer has to search,
  34. load, and run the program, STRINGS's commands execute with the same speed
  35. as do such internal COMMAND.COM functions as COPY, RENAME, and DELETE.
  36.  
  37.      The new program itself bears the same name, STRINGS.COM, as its
  38. predecessor.  That allows you to upgrade instantly simply by copying the
  39. new program over the old. To avoid confusion, I will refer to the original
  40. version of the utility as STRINGS1. If you have never used STRINGS1,
  41. reading through the original article will be helpful, but I'll try to
  42. explain enough here to make that unnecessary.
  43.  
  44.     To assemble the source you will need an assembler compatible with
  45. Microsoft's MASM 2.0.  The commands to create STRINGS.COM are:
  46.  
  47.                              MASM STRINGS;
  48.                              LINK STRINGS;
  49.                              EXE2BIN STRINGS STRINGS.COM
  50.  
  51.  
  52. USING STRINGS
  53.  
  54.      At first sight, the complete syntax for STRINGS.COM may seem
  55. dauntingly complex:
  56.  
  57.      STRINGS [/?][/M][/Q][/Pc][/Bn][/I][/U] [env var =] FUNCTION [Params]
  58.  
  59. But it's a lot easier to use than it looks.  One reason is that, in
  60. addition to this article, the on-screen help facilities are extensive.
  61. Simply enter STRINGS at the DOS prompt and you'll get an explanation of
  62. every item in the syntax line above. Entering STRINGS /? will give you a
  63. complete list of all the commands denoted by FUNCTION, and
  64.  
  65.                            STRINGS /? FUNCTION
  66.  
  67. will spell out the purpose, usage, and Prams (parameters) of each
  68. individual command.  Note that in both of these last two commands the
  69. /? can be replaced by /HELP.
  70.  
  71.     Many STRINGS commands require no arguments; for these you just enter
  72.  
  73.                            STRINGS FUNCTION
  74.  
  75. For example, to return the last available drive letter you simply enter:
  76.  
  77.  
  78.                            STRINGS LASTDRIVE
  79.  
  80. STRINGS will respond by displaying the last available drive letter on
  81. your system.
  82.  
  83.     For commands that do take input parameters, the arguments are
  84.  separated by commas.  For example, the command LEFT, which returns the
  85. first n characters (including spaces) of a string, has two parameters:
  86. the input string and the number of characters to return.  Thus,
  87.  
  88.  
  89.                            STRINGS LEFT This is a string, 9
  90.  
  91. will return the left nine characters ``This is a".  Note the comma
  92. separating the two parameters in the command line.
  93.  
  94.     The results of any STRINGS command can be assigned to an environment
  95. variable.  Simply insert the name for the variable and an equals sign
  96. between STRINGS and FUNCTION.  For example, by changing the previous
  97. example to
  98.  
  99.  
  100.                            STRINGS ANSWER =LEFT This is a string, 9
  101.  
  102. STRINGS will assign the string ``This is a'' to the environment variable
  103. ANSWER.
  104.  
  105.     As shown above, STRINGS has seven command line switches:
  106. /M, /Pc, /Q, /Bn, /I, /U and /?.  The switch must be included on the
  107. command line before the environment variable or, if no variable is
  108. specified, before the command.
  109.  
  110.     By default, STRINGS stores variables in the Active environment,
  111. which is created by the current copy of COMMAND.COM.  If the /M switch
  112. is used, however, STRINGS stores variables in the master environment,
  113. which is created by COMMAND.COM when DOS starts.
  114.  
  115.     In Windows, while each DOS box has its own Active environment, all
  116. share the Master environment.  By using the /M switch, variables can be
  117. read by all programs, including those in individual Windows DOS boxes.
  118. The /M switch is also useful when you want to preserve a variable
  119. assignment you make while shelled out from a program, for the local
  120. environment is lost when you exit from DOS back into your application.
  121.  
  122.     Reverting to the previous example, to assign the results to the
  123. environment variable RESULT in the Master environment, the command would
  124. be
  125.  
  126.                    STRINGS /M RESULT = LEFT This is a string, 9
  127.  
  128.     The MASTERVAR command returns the string assigned to a variable in
  129. the Master environment.  For example, the command
  130.  
  131.                           STRINGS MASTERVAR RESULT
  132.  
  133. returns the string assigned to the RESULT environment variable even if
  134. this command is executed in a different DOS box from the one that was
  135. used in previous examples!
  136.  
  137.      The /Pc (or Parse) switch tells STRINGS to use the c character
  138. rather than the comma to separate multiple parameters.  This switch
  139. allows you to work with strings that contain commas.
  140.  
  141.     The /Q (or Quiet) switch, which was added in a maintenance release
  142. of STRINGS 1.0, prevents STRINGS from writing to the screen. This switch
  143. is useful if the STRINGS command may produce an error message that you
  144. don't want displayed on the screen.
  145.  
  146.     New in STRINGS 2.0 is the /Bn switch, which is used to change the number
  147. base that STRINGS uses to interpret numbers. STRINGS defaults to base 10
  148. arithmetic, but by using the /B switch, you can set the base to any number
  149. from 2 to 16.  Thus, while the statement
  150.  
  151.                                          STRINGS ADD 9, 1 
  152.  
  153. returns the standard value 10, the statement
  154.  
  155.                                          STRINGS /B16 ADD 9, 1 
  156.  
  157. returns the ``number'' A, since A in hexadecimal (base 16) is 10 in decimal.
  158. You'll want to use the /B switch working with several of the new STRINGS
  159. commands, where it is more appropriate to use hexadecimal than decimal
  160. numbers.
  161.  
  162.     If your system is running DOS 3.3 or later, using the /I switch installs
  163. STRINGS as a resident extension of COMMAND.COM.  (How STRINGS actually
  164. accomplishes this will be discussed later.) Unlike most TSRs, which are
  165. installed at startup, STRINGS works best if it is installed only when
  166. and for as long as needed; it should be removed from memory once the
  167. batch file has completed in order to avoid wasting valuable system
  168. memory.  To uninstall STRINGS, you simply use the /U switch.
  169.  
  170.     Installing STRINGS as a resident extension does not alter the syntax
  171. of any of its commands. The speed advantage is dramatic. The disadvantage,
  172. however, is that once installed, STRINGS (like all internal COMMAND.COM
  173. commands) cannot return an exit code to COMMAND.COM. This means that
  174. while STRINGS is resident, you can't use the handy IF ERRORLEVEL statement
  175. in .BAT files to test the result of STRINGS commands.
  176.  
  177.     If your batch file requires the error level codes returned by STRINGS,
  178. two solutions are available.  The first and most obvious is simply not
  179. to install STRINGS at the start of the batch file.  When not installed,
  180. STRINGS 2.0 returns the same error codes as STRINGS 1.0.
  181.  
  182.     The second solution is to specify explicitly the full path to the
  183. STRINGS.COM file.  When a complete path is specified the resident copy
  184. of STRINGS will ignore the command, thus allowing COMMAND.COM to launch
  185. a second copy of STRINGS as a transient program.  For example, since I
  186. keep STRINGS in my UTIL directory, I can force COMMAND.COM to launch a
  187. second copy of STRINGS with the command:
  188.  
  189.  
  190.                               C:\UTIL\STRINGS sub 12, 15 
  191.  
  192.      The use of the
  193.  
  194.                               /?
  195.  
  196. and
  197.  
  198.                               /? FUNCTION
  199.  
  200. switches to obtain on-line help was discussed earlier.  It should be noted
  201. that on-line help is not available when STRINGS is installed in memory,
  202. since the help text would take up an additional 4,500 bytes of memory.
  203. To get help for a specific command while STRINGS is installed, simply
  204. specify the full path to force execution of a nonresident copy of STRINGS.
  205.  
  206. STRINGS COMMANDS
  207.  
  208.      Providing a detailed explanation of the 70 functions shown in
  209. Figure 1 (see below) is not easy, so I've divided them into 6 groups:
  210. old commands enhanced for STRINGS 2.0, string handling, programmer's, data
  211. and time, system memory, and STRINGS management commands.
  212. The /? FUNCTION help screen will suffice for the functions in STRINGS1 if
  213. you haven't got access to the original article. (A copy of the original
  214. article (STRING1.DOC) is included in the archive STRING.ZIP).
  215.  
  216.     Six commands from STRINGS1 have been enhanced:  CHAR, VAL, ASK,
  217. ADD, SUB, and MUL.  In STRINGS1, the CHAR command was limited to
  218. returning the single ASCII character that corresponded to a decimal
  219. number.  Now in STRINGS, CHAR can take up to ten parameters, so ten
  220. numbers can be converted into ten ASCII characters.
  221. For example, the command 
  222.  
  223.                           STRINGS CHAR 65, 66, 67 
  224.  
  225. returns the string ABC.
  226.  
  227.     The VAL command has been similarly enhanced.  An ASCII string passed
  228. to VAL will produce the series of up to ten decimal numbers that correspond
  229. to the characters in the string. The numbers will be separated by spaces.
  230. For example, the command 
  231.  
  232.                          STRINGS VAL Doug
  233.  
  234. returns the string
  235.  
  236.                          68 111 117 103
  237.  
  238. When appropriate, this format can easily be converted into a series of
  239. hex bytes by using the /B16 switch.  Note that because the capital and
  240. small letters have different ASCII values, VAL is inherently case-sensitive.
  241.  
  242.     The enhanced ASK function prints a string and waits for the user to
  243. enter a response.  Its full syntax is: 
  244.  
  245. STRINGS [dest var =] ASK [Prompt string][,Max chars][,1=* echo 2=No echo]
  246.  
  247.    After entering the Prompt string as the first parameter, you specify
  248. the maximum number of characters the user can use to respond as the second.
  249. The maximum can be any number between 1 and 127. Although STRINGS works
  250. with strings up to 127 characters long, remember that DOS programs can only
  251. accept a command line with a total length of 127 characters.  Thus,
  252. setting an environment variable to a long length may cause DOS to overflow
  253. the command line of a program that uses that variable.
  254.  
  255.     The third and final ASK parameter is a flag that tells STRINGS not
  256. to echo what the user types to the screen.  This allows a .BAT file to
  257. prompt for a password without its becoming visible on the screen.
  258. When the third parameter is a 1, STRINGS echoes asterisks to the screen
  259. in place of the characters being typed.  If the parameter is 2, STRINGS 
  260. does not echo any characters to the screen. If neither flag is specified,
  261. the user response is echoed.
  262.  
  263.     Three of the math functions--ADD, SUB, and MUL--have been revised to
  264. allow you to add or multiply up to 10 different numbers in one STRINGS
  265. command.  For the SUB command, up to nine numbers can be subtracted from
  266. the first number in the series.  Thus, the command 
  267.  
  268.                                  STRINGS SUB 10, 2, 1 
  269.  
  270. returns the value 7, which is computed as 10 - 2 - 1.
  271.  
  272. STRING HANDLING COMMANDS
  273.  
  274.         This first set of the new STRINGS commands goes to the root of the
  275. program's functionality; its ability to manipulate strings.
  276.  
  277.     The PARSE command separates a string into different sections and
  278. returns one of those sections.  This command makes it easy to separate
  279. the different directory strings from the PATH environment variable, for
  280. example.  The full syntax for PARSE is
  281.  
  282. STRINGS [dest var =] PARSE String, section number, Separator char
  283.  
  284. The three PARSE parameters are the string, the section number to return,
  285. and the separator character to be used to differentiate among sections.
  286. The small batch file, CHECKEX.BAT, (listed below in Figure 2) uses the
  287. PARSE command to search the PATH to determine the execution order of the
  288. program name you provide. This is exactly what COMMAND.COM does when it
  289. is asked to launch a program. On my machine, the command 
  290.  
  291.                            CHECKEX brief
  292.  
  293. returned the list
  294.  
  295.                            C:\UTIL\B.BAT
  296.                            C:\EDITORS\BRIEF\B.EXE
  297.  
  298. This return discloses a problem:  If DOS searches the full path, B.BAT
  299. will execute, but B.EXE never will. It seems I should rename that batch
  300. file!
  301.  
  302.     As shown by the STRINGS line in CHECKEX.BAT, the PARSE command here
  303. uses the PATH environment variable as the starting string. It uses the
  304. INDEX environment variable to run through the different directories in
  305. sequence. And it uses the semicolon to tell where one directory ends
  306. and the next one begins on the PATH statement.
  307.  
  308.     ADDCOMMAS is a simple command that inserts commas every three digits in
  309. a number you supply as its argument.  If you enter
  310.  
  311.                            STRINGS ADDCOMMAS 12345678
  312.  
  313. STRINGS will return
  314.  
  315.                            12,345,678
  316.  
  317.     The REPEAT command simply creates a string that consists of the
  318. same character repeated n times.  For example, the command
  319.  
  320.                             STRINGS REPEAT 25, A
  321.  
  322. will return a string with 25 As.  The maximum value for n is 127.
  323.  
  324.     The FILEDATE command returns the date on a file. It takes filename
  325. as its only argument, and the date is returned in a mm-dd-yyyy format.
  326. The FILETIME command similarly returns the time when a file was last
  327. written, in a hh:mm:ss am/pm format.
  328.  
  329.     TRUEVER returns the true DOS version number, regardless of what is
  330. reported by the normal VER command.  With the introduction of the SETVER
  331. device driver in DOS 5.0, you can trick programs into believing that they
  332. are running under a different version of DOS than they actually are.
  333. There are times, however, when you need to know the real DOS version:
  334. hence TRUEVER.  The number returned is the major version number times
  335. 100, plus the minor version number.  For example, in DOS 5.0 the number
  336. returned is 500.
  337.  
  338.     Although the SETVER device driver is only available on DOS 5.0
  339. (and later), the TRUEVER command will still work under DOS versions 2.0
  340. though 4.0; it simply returns the same value as does the STRINGS VER
  341. command.
  342.  
  343.     The FILES command returns the maximum number of files that can be
  344. open on the system at one time.  This number is usually, but not always,
  345. the number shown in the FILES= statement in your CONFIG.SYS file.
  346. Programs such as Windows or Jeff Prosise's UMBFILES can change the
  347. maximum number of files, however, so FILES is a handy way to confirm
  348. that a program will have enough file handles to run.
  349.  
  350.     The LASTDRIVE command returns the last drive letter that can be
  351. assigned to a disk.  This is usually set with the LASTDRIVE= line in
  352. the CONFIG.SYS file, but again, some programs can modify that value.
  353. LASTDRIVE is useful when a batch file must perform an action on all
  354. possible drives in the system.
  355.  
  356.     The CODEPAGE command allows batch files to determine the currently
  357. active codepage.  The codepage number determines the character set your
  358. system uses.  Most US systems use codepage 437, which is the standard
  359. character set. Codepage 850, on the other hand, replaces some of the
  360. graphic characters in the 437 codepage with characters used in European
  361. languages. To query the active codepage, simply enter STRINGS CODEPAGE.
  362.  
  363.     The COUNTRY command returns the country information for the system.
  364. Since DOS 2.0, parameters such as the currency symbol, thousands separator,
  365. and the date format can be configured for different countries. The table
  366. in Figure 3 (see below) shows what the COUNTRY command returns for
  367. different values of the first parameter, assuming you live in the U.S.
  368.  
  369.     Entering STRINGS BIOSDATE returns a string, normally containing the
  370. date, from address F000:FFF5h in the BIOS ROM.  The command assumes the
  371. date will be in the first 8 bytes following the address, as it is in most
  372. PC compatibles.  The command takes no arguments.
  373.  
  374.      The GETKEY command waits for the user to press a key then returns
  375. the ASCII value and its scan code.  While the ASK command is limited to
  376. returning ASCII characters, GETKEY is also able to return non-ASCII keys
  377. such as the cursor keys and function keys. The codes are returned with
  378. the ASCII code first, followed by a space, followed by the scan code.
  379. It is at this point that you can use the PARSE command to operate separately
  380. on the ASCII and scan codes returned by the keystroke.
  381.  
  382.     The next four commands--AND, OR, XOR, and NOT--extend the math commands
  383. to logical operations.  The AND command returns the logical AND of the
  384. parameters you supply.  Likewise, the OR and XOR commands return the
  385. logical OR and exclusive OR of their respective parameters. Like the ADD,
  386. SUB, and MUL commands, the AND and OR commands can take up to ten
  387. parameters.  XOR, of course, takes only two. The NOT command returns the
  388. one's complement of its single parameter.
  389.  
  390.     The CONVERT command, which converts a number to a different base,
  391. became necessary once the /B switch was introduced.  This command takes
  392. two parameters:  the number to be converted and the new number base.
  393. As with all commands, both the number and new base parameters are
  394. interpreted in the base specified in the /B switch.  For example, to
  395. convert the hexadecimal (base 16) number 2FB to decimal, the command
  396. would be
  397.  
  398.                         STRINGS /B16 CONVERT 2FB, A
  399.  
  400. Note here that the second parameter, A, is not the character A, but rather
  401. the number 10, in hexadecimal.  Going the other way, the command
  402.  
  403.                         STRINGS CONVERT 763, 16
  404.  
  405. returns the hexadecimal number 2FB. (Because the default base for STRINGS
  406. is base 10, the /B switch is not required in this case.)
  407.  
  408. TIME & DATE COMMANDS
  409.  
  410.      The next four commands return times and dates.  The DAY function
  411. returns the current day of the week:STRINGS DAY will return Tuesday if
  412. today is Tuesday.  As an added feature, if the DAY command is passed
  413. a number between 1 and 7, it returns the day corresponding to that number.
  414. STRINGS DAY 6 returns the string Friday, for example.
  415.  
  416.     The MONTH command is entirely similar to the DAY command, and again,
  417. if passed a number between 1 and 12, it returns the month corresponding
  418. to that number.
  419.  
  420.     The DATE command returns the current date in a mm-dd-yyyy format.
  421. The Time command similarly returns the current time in a hh:mm:ss am/pm
  422. format. Users requiring a different format for the time and date can
  423. easily use the multitude of STRINGS commands to present the data in any
  424. form they wish.
  425.  
  426. SYSTEM MEMORY
  427.  
  428.      The enhanced STRINGS contains a number of commands that deal with
  429. system memory. MEMTOTAL returns the total conventional (DOS) memory
  430. available to the system, and MEMFREE returns the amount of conventional
  431. memory still available for use.  Note, however, that the MEMFREE command
  432. will respond differently when STRINGS is installed as resident.
  433. COMMAND.COM does not release its memory when resident commands are
  434. executed, so if STRINGS is resident when this call is made, the amount
  435. of free conventional memory indicated will be small or nonexistent.
  436.  
  437.     The XMSTOTAL command returns the total amount of extended memory in
  438. the system, and XMSFREE returns the amount of free extended memory.
  439. Normally, extended memory is managed by an extended memory (XMS) manager,
  440. such as HIMEM.SYS.  If no XMS manager is present, STRINGS uses a BIOS
  441. Int 15h call to determine the amount of extended memory. In this case,
  442. as there is no memory manager present to differentiate between free and
  443. used extended memory, both the XMSFREE and XMSTOTAL calls will return
  444. the same number.  XMSVER returns the version of the XMS memory manager
  445. in use; if none is present, the command returns 0.
  446.  
  447.     Expanded memory is correspondingly queried with the EMSTOTAL, EMSFREE,
  448. and EMSVER commands. Again, if no expanded memory manager is installed,
  449. EMSVER will return 0.
  450.  
  451.      The final memory command is UMBLARGE.  This command returns the size
  452. of the largest free upper memory block (UMB).  UMBs are blocks of memory
  453. that reside between the video memory at A000h and the BIOS ROM at E000h
  454. or F000h.  This command is useful for determining whether there is room
  455. in upper memory for TSRs.
  456.  
  457. PROGRAMMER'S COMMANDS
  458.  
  459.      The next series of commands are designed for the PC programmer.
  460. They allow batch files to actually perform functions previously reserved
  461. for .COM and .EXE files.
  462.  
  463.      PEEK, the first of these commands, allows a batch file to read a
  464. series of bytes from memory.  The syntax of the PEEK command is
  465.  
  466. STRINGS [dest var=] PEEK Segment, Offset [,Number of bytes] [,Word flag]
  467.  
  468.      The first two command parameters are the segment and offset of the
  469. memory address to be read.  The optional third parameter is the number
  470. of bytes to be read; if this parameter absent, STRINGS returns 1 byte.
  471. The fourth and final parameter is also optional.  If it is 2, STRINGS
  472. will return the bytes read from memory in a 2-byte, or word, format.
  473.  
  474.     To illustrate, in order to see which shift keys are pressed, you
  475. can use the PEEK command to read the keyboard status bytes at 40:17 and
  476. 40:18 hex.  The command would be
  477.  
  478.                                  STRINGS /b16 PEEK 40, 17, 2.
  479.  
  480.      The complementary POKE command writes data directly to memory.
  481. Again, the first parameter is the segment and the second is the offset
  482. of the address.  The remaining parameters, up to an additional eight,
  483. are the bytes to write to memory. Note that while these bytes are being
  484. written, interrupts are disabled so the system doesn't read partially
  485. written data. The following short batch file uses the PEEK, AND, and
  486. POKE commands to turn off the keyboard NumLock.
  487.  
  488.                        STRINGS /b16 shift = PEEK 40, 17
  489.                        STRINGS /b16 shift = AND %SHIFT%, DF
  490.                        STRINGS /b16 POKE 40, 17, %SHIFT%
  491.                        SET shift=
  492.  
  493.      You could also use the POKE command to overwrite the DOS command
  494. interrupt vector (Interrupt 21) with zeros, the command would be
  495.  
  496.                        STRINGS /B16 POKE 0, 84, 0, 0, 0,0
  497.  
  498. Don't try this example, however, for it will surely lock up your machine!
  499. As this last example illustrates, POKE--and other programming commands
  500. that will be discussed shortly--can easily be misused and thereby cause
  501. harm.  So make sure you fully understand a command before you use it.
  502.  
  503.     The IN and OUT commands give batch files the ability to read and
  504. write to system I/O (Input/Output) ports. It is through these ports that
  505. the system talks to disk drive controllers and to devices connected to
  506. serial and/or parallel ports. The IN command takes only one parameter,
  507. namely, the address of the I/O port. This address is the first of the
  508. OUT command's two parameters, the second being the data byte to write
  509. to that port.
  510.  
  511.     An amusing example that demonstrates the use of the IN and OUT
  512. commands is provided by the batch files NOIZE and MARY, which are listed
  513. below in Figure 4.  NOIZE.BAT plays a note on the PC speaker by toggling
  514. the speaker control bits in the keyboard control I/O port (I/O address 61h).
  515. The proper timing for the note is determined by using PC hardware timer 3.
  516. MARY.BAT calls NOIZE.BAT to play the familiar ``Mary had a little lamb.''
  517. My thanks to Neil Rubenking for this entertaining example.
  518.  
  519.     The INTERRUPT command is easily the most powerful--and therefore
  520. dangerous--command in the STRINGS repertoire. The command calls an
  521. interrupt and returns the values of the registers. The ten parameters for
  522. this command specify the interrupt number and the values of most of the
  523. processor registers at the time the interrupt is called.  Its syntax is
  524. the following:
  525.  
  526.      STRINGS INTERRUPT Int Number, AX, BX, CX, DX, DI, SI, BP, DS, ES
  527.  
  528.     The string returned is a series of numbers, separated by spaces,
  529. that represent the value in each of the registers at the time the
  530. interrupt returns.  The format for the returned string is
  531.  
  532.                   AX BX CX DX DI SI BP DS ES Flags
  533.  
  534.     The Flags register contains such flags as Carry, Zero, Sign, and
  535. Interrupt Enable.  Just as a value is returned for each of the other
  536. registers, a value is also returned for the Flags register.  It is the
  537. responsibility of the batch program to examine the value returned for
  538. the Flags register to determine the state of any flags that might be
  539. important.  For this purpose, the AND and OR commands often prove useful.
  540.  
  541.     An example of this complex command in action will be helpful. Suppose
  542. you want to know the address of the InDOS flag.  The newly documented
  543. function for getting the InDOS address is Interrupt 21, AH = 34.  The
  544. STRINGS command to enter would be 
  545.  
  546.         STRINGS /B16 INTERRUPT 21, 3400, 0, 0, 0, 0, 0, 0, 0, 0
  547.  
  548.     The /B16 switch is used to tell STRINGS to ``talk'' in hexadecimal,
  549. which is handy because most PC programming is done in base 16.  The 21
  550. indicates that you want STRINGS to call Interrupt 21h, the DOS command
  551. dispatcher.  The 3400 indicates that AX is to be loaded with 3400h when
  552. the interrupt is called.  In fact, you only need to load AH (with 34h),
  553. but the command has no way of loading the individual byte halves of the
  554. registers.  Thus, you end up loading AX with 3400, which puts 34 in AH
  555. and 00 in AL.  The remaining registers for this interrupt are not
  556. important, and actually they don't have to be included at all. STRINGS
  557. loads 0 in the registers not specified.
  558.  
  559.     On my machine running MS-DOS 5.0, the command above returns the
  560. string
  561.  
  562.           3400 321 0 0 0 0 0 0 116 7246
  563.  
  564. The INTERRUPT command always returns a string with ten numbers, each
  565. separated by a space.  Because the /B16 switch was used, all the values
  566. are in hexadecimal.  The first number, 3400, is the value of the AX
  567. register when the interrupt returns.  The important values, however,
  568. are 321, the value of BX on the return; and 116, which is the returned
  569. value of ES.  The MS-DOS Programmer's Reference indicates that the address
  570. of the InDOS flag will be returned in ES:BX.
  571.  
  572.     You can now use the PEEK command to check the state of the InDOS
  573. flag.  That command would look like this:
  574.  
  575.                        STRINGS /B16 PEEK 116 321
  576.  
  577.     Although knowing the address of the InDOS flag has little use for
  578. batch file programming, other interrupts can come in quite handy.  The
  579. undocumented interrupt 21 AX=5200 returns a pointer to DOS's list of
  580. lists. This pointer is quite useful for checking out the current state
  581. of the machine.  Shortly I'll present a batch file that uses the list of
  582. lists to determine the current memory usage for the system.
  583.  
  584.     The final programmer's command is SCAN. This command searches memory
  585. for a series of bytes.  The segment to search and the starting offset
  586. are specified in the first two parameters.  The remaining parameters
  587. (up to an additional eight) are the bytes to use in the search.
  588. For example, to search the segment 23h for the byte series 10 20 30 40
  589. the command would be
  590.  
  591. STRINGS /B16 SCAN 23, 0, 10, 20, 30, 40
  592.  
  593. Since SCAN searches only the segment specified, additional SCAN commands
  594. are needed for any searches beyond the original segment.
  595.  
  596.     When used in conjunction with the improved VAL command, SCAN can
  597. search for an ASCII string in memory. An example is shown in the following
  598. batch code fragment, which searches the DOS kernel for the string ``NUL":
  599.  
  600. STRINGS /B16 VALSTR = VAL NUL 
  601. STRINGS /B16 /P SCAN 116 0 %VALSTR%
  602.  
  603.     As previously discussed, the VAL command returns the ASCII numbers
  604. for each of the characters in the first parameter. In this case, because
  605. the /B16 switch is used, VAL returns the numbers 4E 55 4C as a series of
  606. hex bytes.  These bytes are assigned to the VALSTR environment variable.
  607. The new InDOS command mentioned above starts at offset 0 and uses the
  608. VALSTR environment variable for its remaining arguments.  On my machine,
  609. this fragment returns the address 116 52, which is the address for the
  610. NUL device driver name.  That address is important because the NUL device
  611. driver is the first in the DOS device driver chain.
  612.  
  613.     Two additional notes about this batch fragment are in order.  First,
  614. the lack of commas separating the parameters in the SCAN command is not
  615. a typo.  The /P switch is used here to change the parse character to a
  616. space.  This is convenient, since the VAL command returns its numbers
  617. separated by spaces.
  618.  
  619.     The second important detail concerns the consistent use of the /B
  620. switch.  While it may not seem that the /B switch would be needed for
  621. either command, if it is used in the VAL command it must be used in the
  622. SCAN command.  Since VAL uses a /B16 switch, it returns its numbers
  623. in hex.  Because the result from the VAL command is used in the SCAN
  624. command, SCAN must use the same base.  Why was the /B16 switch used in
  625. the first place? Remember that the DOS segment returned by the INTERRUPT
  626. command was returned in hexadecimal, which forced the use of the /B
  627. switch since we used that number.  Just follow this simple rule:  If
  628. parameters are shared across STRINGS commands, they should use the same
  629. base, or you should use the CONVERT command to change the parameters
  630. to the proper base.
  631.  
  632. STRINGS MANAGEMENT
  633.  
  634.      The final group of new STRINGS commands are to manage STRINGS itself.
  635. STRINGSVER returns the version of STRINGS currently being used.  Since
  636. this command did not exist in the first version of STRINGS, calling it
  637. with STRINGS1 will result in an error message and a return code of 1.
  638. If STRINGSVER returns a nonzero ERRORLEVEL code, then STRINGS 1.x is
  639. running.  For the present version of STRINGS, the STRINGSVER command
  640. returns the ASCII string 200 and a return code of 0.
  641.  
  642.     The INSTALLED command returns a 1 if STRINGS is currently installed
  643. as a TSR extension to COMMAND.COM. If STRINGS is not installed, a 0 is
  644. returned.  This command is useful for those situations in which a
  645. STRINGS command might produce different results if the utility were
  646. installed.  MEMFREE represents one such case, and the use of return
  647. codes may be another.
  648.  
  649. INSIDE STRINGS
  650.  
  651.      For the most part, the enhanced version of strings simply involved
  652. adding procedures for the new functions. The main change to the program
  653. itself was the rewriting of the command parsing routine to use less memory.
  654. This was necessary so that STRINGS could be turned into a TSR. Of greatest
  655. programming interest, however, is the hook into COMMAND.COM's internal
  656. command dispatcher.
  657.  
  658.     In Undocumented DOS, coauthor Jim Kyle has an informative chapter on
  659. command interpreters. It describes an undocumented ``back door'' into
  660. COMAND.COM that allows TSRs to hook into the internal command dispatcher.
  661. This back door was first included in DOS 3.3 so that DOS's APPEND command
  662. could check on any subsequent APPEND commands. Fortunately for programmers,
  663. that door has remained open in all later DOS releases.
  664.  
  665.     When you enter a command at the DOS command line, COMMAND.COM must
  666. determine whether the command is an internal function to be executed or
  667. an external program that must be launched. Before making its decision,
  668. COMMAND.COM calls the Multiplex Interrupt (Int 2Fh) with AX equal to
  669. AE00h. At the time of the call, DX is loaded with FFFFh, BX is pointing
  670. to a buffer that contains an exact replica of the command line just typed,
  671. and SI points to a buffer that contains the potential command in
  672. uppercase preceeded by a length byte.
  673.  
  674.     TSRs such as STRINGS that hook into this call must compare the
  675. command to which SI points with the command they wish to handle. For
  676. STRINGS, that means checking to see whether SI is pointing to the ASCII
  677. string "STRINGS".
  678.  
  679.     A TSR that wants to claim the command puts 0FFh in AL, copies the
  680. comand line pointed to by BX into an internal buffer, and returns to
  681. COMMAND.COM.  Otherwise the TSR must pass the Multiplex request down
  682. the interrupt chain with all registers unmodified.
  683.  
  684.     If a TSR claims the command, COMMAND.COM calls the Multiplex
  685. Interrupt again, this time with AX loaded with AE01h.  Having claimed it,
  686. the TSR must now execute the command.  While most of the registers during
  687. this call are the same as in the AE00h call, Kyle recommends that a TSR
  688. should copy the buffer from the earlier AE00h call because not all the
  689. registers are explicitly loaded before the AE01h call.  Once the command
  690. has been completed, the TSR should zero the size byte in the buffer to
  691. which SI points.  This tells COMMAND.COM that the command has been
  692. processed.
  693.  
  694.     While STRINGS doesn't provide every possible function a batch file
  695. might want, the inclusion of such commands as PEEK, POKE, and INTERRUPT
  696. allow the programmer to create just about any command.  An an example of
  697. this power is shown in BATMEM.BAT, which is listed below in Figure 5.
  698.  
  699.     BATMEM scans the DOS memory blocks and displays the blocks that are
  700. being used as well as the ones that are free. BATMEM is similar to the
  701. MEM command that has been included in DOS since version 4.0.  Among the
  702. STRINGS functions BATMEM uses are INTERRUPT, PARSE, CHAR, PEEK, and
  703. ADDCOMMAS.
  704.  
  705.     Notice that in BATMEM, STRINGS is installed with /I at the beginning
  706. of the batch file and removed with /U at the end. These two switches double
  707. the execution speed.  If you don't want STRINGS installed and removed,
  708. simply delete the /I and /U switches; the remainder of the batch file
  709. will be unaffected.
  710.  
  711.     Programs like BATMEM give but a taste of the world STRINGS opens to
  712. enterprising batch file writers.  To supplement STRINGS own commands, you
  713. may wish to acquire Michael J. Mefford's excellent BATCHMAN utility in
  714. the January 30, 1990 issue of PC Magazine. Like STRINGS, BATCHMAN is
  715. available on PC MagNet.
  716.  
  717.     The ability to perform low-level actions, coupled with the convenient
  718. features of STRINGS's high-level commands, provide a wealth of new
  719. opportunities for the once-lowly batch file. Try STRINGS, and your batch
  720. files will never be the same.
  721. ----------------------------------------------------------------------------
  722. DOUGLAS BOLING IS A CONTRIBUTING EDITOR TO PC MAGAZINE.
  723. ----------------------------------------------------------------------------
  724.  
  725.                        STRINGS COMMANDS
  726.  
  727.  
  728.              FUNCTION AND SYNTAX                 RETURNS
  729.  
  730.  
  731. New          2FCHECK n or Alias              Returns status of programs hooked
  732.                                              to the Multiplex Interrupt.
  733.  
  734. Enhanced     ADD n1, n2[,n3][,n4][,n5]       The sum of the parameters.
  735.              [,n6][,n7][,n8][,n9][,n10]
  736.  
  737. New          ADDCOMMAS n                     n parsed with commas every 3
  738.                                              digits.
  739.  
  740. New          AND n1, n2[,n3][,n4][,n5]       The logical AND of the
  741.              [,n6][,n7][,n8][,n9][n10]       parameters.
  742.  
  743. Enhanced     ASK [Prompt string]
  744.              [, Max chars][,1=No echo]       A response from a user.
  745.  
  746. New          BIOSDATE                        The date for the ROM BIOS.
  747.  
  748. Enhanced     CHAR c[c][c][c][c]
  749.              [c][c][c][c][c][c]              ASCII number of character.
  750.  
  751. New          CODEPAGE                        The activecode page.
  752.                                              Requires DOS 3.3 or later.
  753.  
  754. New          CONVERT n, New Base             A number with the specified
  755.                                              base.
  756.  
  757. New          COUNTRY                         The country code for the
  758.                                              system.
  759.  
  760. New          DATE                            The current date in mm-dd-yyyy
  761.                                              format.
  762.  
  763. New          DAY [Index (1=Sunday, 2=Mon]    The name of the day of the
  764.                                              week.
  765.  
  766.              DIV n, n                        The quotient of two numbers.
  767.  
  768. New          EMSFREE                         The amount of free expanded
  769.                                              memory.
  770.  
  771. New          EMSTOTAL                        The amount of expanded memory.
  772.  
  773. New          EMSVER                          The version of the expanded
  774.                                              memory driver.
  775.  
  776.              ENVFREE                         Bytes free in the environment.
  777.  
  778.              ENVSIZE                         The size of the environment.
  779.  
  780. New          FILEDATE Filename               The date of a file.
  781.  
  782.              FILEDIR Filename                The directory of a filename.
  783.  
  784.              FILEDRIVE Filename              The drive of a filename.
  785.  
  786.              FILEEXT Filename                The file extension.
  787.  
  788.              FILENAME Filename               The filename.
  789.  
  790. New          FILES                           The total number of files that
  791.                                              can be open.
  792.  
  793.              FILESIZE Filename               The size of a file.
  794.  
  795. New          FILETIME Filename               The time of a file.
  796.  
  797.              FIND String, Findstring         The position of Findstring in
  798.                                              String.
  799.  
  800.              FINDC String, Findstring        The position of Findstring
  801.                                              in String. Case sensitive.
  802.  
  803. New          GETKEY                          The scan code and ASCII value of
  804.                                              next key pressed.
  805.  
  806. New          HELP [Strings Command]         The help text for the specified
  807.                                              STRINGS command.
  808.  
  809. New          IN Port number                  A byte from an I/O port.
  810.  
  811. New          INSTALLED                       A non-zero number if Strings
  812.                                              installed as TSR.
  813.  
  814. New          INTERRUPT Int n, AX, BX, CX,
  815.          DX, DI, SI, BP, DS, ES         The registers from an interrupt.
  816.                                              Dangerous!
  817.  
  818.              INWIN                     1 if Windows running.
  819.  
  820. New          LASTDRIVE                       The letter of the last possible
  821.                                              drive.
  822.  
  823.              LEFT String, n                  The left n characters.
  824.  
  825.              LENGTH String                   The String length.
  826.  
  827.              LINESIZE Filename               The number of lines.
  828.  
  829.              LOWER String                    The string in all lowercase.
  830.  
  831.              MASTERENV                       The address of the master
  832.                                              environment
  833.  
  834.          MASTERVAR Variable Name         A variable from the Master
  835.                                              environment.
  836.  
  837. New          MEMFREE                         The largest block of free
  838.                                              conventional memory.
  839.  
  840. New          MEMTOTAL                        The amount of conventional
  841.                                              memory.
  842.  
  843.              MID String, Start c, Length     The middle n characters.
  844.  
  845. New          MONTH [Index (1=January)]       The name of the month
  846.  
  847. Enh          MUL n1, n2[,n3][,n4][,n5]
  848.              [,n6][,n7][,m8][,n9][,n10]      The product of the parameters.
  849.  
  850. New          NOT n                           The logical NOT of n.
  851.  
  852. New          OR n1, n2[,n3][,n4][,n5]
  853.              [,n6][,n7][,n8][,n9][,n10]      The logical OR of the parameters.
  854.  
  855. New          OUT Port n, Output byte         Writes a byte to an I/O port.
  856.  
  857. New          PARSE String, Token n,
  858.              Token separator char            The nth token from a string.
  859.  
  860. New          PEEK Segment, Offset
  861.              [, n bytes [,Word flag]]        A series of bytes from memory.
  862.  
  863. New          POKE Segment, Offset,
  864.              b1[,b2][,b3][,b4]
  865.              [,b5][,b6][,b7][,b8]            Writes up to 8 bytes to memory.
  866.  
  867.  
  868.              READ Filename, line number      A line from a file.
  869.  
  870. New          REPEAT n of chars, c            A string of n characters c.
  871.  
  872.              RIGHT String, n                 The right n characters.
  873.  
  874. New          SCAN Segment, Starting
  875.              Offset, b1 [,b2]                The offset of a series of
  876.                                              bytes in memory.
  877.  
  878. Enh          SUB n1, n2[,n3][,n4][,n5]
  879.              [,n6][,n7][,n8][,n9][,n10]      The difference of two numbers.
  880.  
  881. New          TIME                            The current time.
  882.  
  883.              TRUENAME Filename               The complete filename.
  884.  
  885. New          TRUEVER                         The true DOS verison.
  886.                                              Requires DOS 5.0 or later.
  887.  
  888. New          UMBLARGE                        The largest block of free
  889.                                              upper memory.
  890.  
  891.              UPPER String                    The string in all uppercase.
  892.  
  893. Enh          VAL n1, n2[,n3][,n4][,n5]
  894.              [,n6][,n7][,n8][,n9][,n10]      ASCII characters for a number.
  895.  
  896.              VER                             The DOS version number.
  897.  
  898.              WRITE Filename, String         Appends a string to the end
  899.                                              of a file.
  900.  
  901. New          XMSFREE                         The amount of free extended
  902.                                              memory.
  903.  
  904. New          XMSTOTAL                        The amount of extended memory.
  905.  
  906. New          XMSVER                          The version of the extended
  907.                                              memory driver.
  908.  
  909. New          XOR n, n                        The exclusive OR of two numbers.
  910.  
  911. Figure 1:
  912. All commands shown above begin with STRINGS [dest var =].  In the listing, n
  913. designates a number, c a character, and b a byte.
  914. ----------------------------------------------------------------------------
  915.  
  916. CHECKEX.BAT
  917.  
  918. rem----------------------------------------------------
  919. rem CHECKEX.BAT - Scans the path for a program name.
  920. rem----------------------------------------------------
  921. @echo off
  922. SET index=1
  923. if exist %1.com echo %1.com
  924. if exist %1.exe echo %1.exe
  925. if exist %1.bat echo %1.bat
  926. :loop
  927.    STRINGS pdir = PARSE %path%, %index%,;
  928.    IF . == .%pdir% GOTO exit
  929.    if exist %pdir%\%1.com echo %pdir%\%1.com
  930.    if exist %pdir%\%1.exe echo %pdir%\%1.exe
  931.    if exist %pdir%\%1.bat echo %pdir%\%1.bat
  932.    STRINGS index = ADD %index%, 1
  933. GOTO loop
  934. :exit
  935. SET index=
  936. SET pdir=
  937.  
  938. Figure 2: CHECKEX.BAT shows the execution priority order for a program
  939. name that might be present on a path in .COM, .EXE, and .BAT forms.
  940. ------------------------------------------------------------------------
  941.  
  942.                       COUNTRY CODES
  943.  
  944. ==================================================================
  945.  
  946. First Parameter Value   Returns                  Comments
  947. --------------------------------------------------------------------
  948. No parameter            Country Code             Active country code
  949. 0                       Date Format              0 = mm-dd-yyyy
  950. 1                       Currency Symbol          $ for the US
  951. 2                       Thousands Separator      , for the US
  952. 3                       Decimal Separator        . for the US
  953. 4                       Date Separator           - for the US
  954. 5                       Time Separator           : for the US
  955. 6                       Currency Format          0 for the US
  956. 7                       Currency Places          2 for the US
  957. 8                       Time Format              0 = 12-hour format
  958. 9                       Data Separator           , for the US
  959.  
  960.  
  961. Figure 3: These are the different values returned when 1 is supplied as
  962. the parameter for the COUNTRY command.
  963. ------------------------------------------------------------------------
  964.  
  965.  
  966. NOIZE.BAT
  967.  
  968. @ECHO OFF
  969. REM ------------------------------------------------------------
  970. REM NOIZE.BAT - by Neil Rubenking
  971. REM
  972. REM Enter a frequency as its command line parameter and it
  973. REM starts a note of that frequency.  Enter NO parameter and it
  974. REM shuts the speaker up.
  975. REM ------------------------------------------------------------
  976. IF '%1'=='' GOTO Stop
  977. STRINGS inv=DIV 1193180,%1
  978. STRINGS inv=CONVERT %inv%,16
  979. STRINGS inv=RIGHT 0000%inv%,4
  980. STRINGS Hi=LEFT %inv%,2
  981. STRINGS Lo=RIGHT %inv%,2
  982. STRINGS /b16 OUT 43,B6
  983. STRINGS /b16 OUT 42,%lo%
  984. STRINGS /b16 OUT 42,%hi%
  985. STRINGS /b16 AL=IN 61
  986. STRINGS /b16 AL=OR %AL%,3
  987. STRINGS /b16 OUT 61,%AL%
  988. GOTO End
  989. :Stop
  990. STRINGS /b16 AL=IN 61
  991. STRINGS /b16 AL=AND %AL%,FC
  992. STRINGS /b16 OUT 61,%AL%
  993. :End
  994. SET al=
  995. SET inv=
  996. SET hi=
  997. SET lo=
  998.  
  999. @ECHO OFF
  1000. REM ------------------------------------------------------------
  1001. REM MARY.BAT - by Neil Rubenking
  1002. REM
  1003. REM Plays a familar tune
  1004. REM ------------------------------------------------------------
  1005. STRINGS /I /Q
  1006. CALL NOIZE 330
  1007. CALL NOIZE 294
  1008. CALL NOIZE 262
  1009. CALL NOIZE 294
  1010. CALL NOIZE 330
  1011. CALL NOIZE 330
  1012. CALL NOIZE 330
  1013. CALL NOIZE 330
  1014. CALL NOIZE 294
  1015. CALL NOIZE 294
  1016. CALL NOIZE 294
  1017. CALL NOIZE 294
  1018. CALL NOIZE 330
  1019. CALL NOIZE 392
  1020. CALL NOIZE 392
  1021. CALL NOIZE 392
  1022. CALL NOIZE
  1023. STRINGS /U /Q
  1024.  
  1025. Figure 4: NOIZE.BAT and MARY.BAT combine to play "Mary Had a Little Lamb."
  1026. --------------------------------------------------------------------------
  1027.  
  1028. BATMEM.BAT
  1029.  
  1030. @echo off
  1031. rem -------------------------------------------------------------
  1032. rem
  1033. rem A batch file that returns a memory scan
  1034. rem BATMEM.BAT
  1035. rem Copyright 1992 Douglas Boling
  1036. rem
  1037. rem -------------------------------------------------------------
  1038. rem
  1039. rem First, get the pointer to the list of lists
  1040. rem
  1041. strings /i /b16 iret = interrupt 21, 5200
  1042. strings /b16 lloff = parse %iret%, 2
  1043. strings /b16 llseg = parse %iret%, 9
  1044. set iret=
  1045.  
  1046. rem
  1047. rem First memory block kept at ListOfList - 2
  1048. rem
  1049. strings /b16 lloff = sub %lloff%, 2
  1050. strings /b16 memseg = peek %llseg%, %lloff%, 2, 2
  1051.  
  1052. echo.
  1053. echo  Block Owner Size Program
  1054. echo  --------------------------------
  1055.  
  1056. strings /b16 totalmem = add %memseg%, 1
  1057. set freemem=0
  1058. :loop
  1059.    rem
  1060.    rem Parse the memory arena header
  1061.    rem
  1062.    strings /b16 memtype = peek %memseg%, 0, 1
  1063.    strings /b16 memowner = peek %memseg%, 1, 2, 2
  1064.    strings /b16 memsize = peek %memseg%, 3, 2, 2
  1065.  
  1066.    strings /b16 memtemp = peek %memseg%, 8, 8
  1067.    strings /b16 /p  memtemp = char %memtemp%
  1068.  
  1069.    strings /b16 memseg = add %memseg%, 1
  1070.    rem
  1071.    rem If block not PSP, don't print block name
  1072.    rem
  1073.    set memname=
  1074.    set diff=-1
  1075.  
  1076.    strings /b16 /q diff = sub %memseg%, %memowner%
  1077.    if .%diff% == .0 goto skip1
  1078.    goto skip2
  1079.    :skip1
  1080.       set memname=%memtemp%
  1081.    :skip2
  1082.  
  1083.    if NOT %memowner% == 0000 goto skip3
  1084.       set memowner=FREE
  1085.       strings /b16 freemem = add %freemem%, %memsize%
  1086.    :skip3
  1087.    rem
  1088.    rem OK, print the results
  1089.    rem
  1090.    echo  %memseg% %memowner% %memsize% %memname%
  1091.  
  1092.    strings /b16 memseg = add %memseg%, %memsize%
  1093.    strings /b16 totalmem = add %memsize%, %totalmem%
  1094.    strings /b16 totalmem = add %totalmem%, 1
  1095.  
  1096. if %memtype% == 4D goto loop
  1097.  
  1098. echo.
  1099.  
  1100. strings /b16 memsize = mul %memsize%, 10
  1101. strings /b16 memsize = convert %memsize%, A
  1102. strings memsize = addcommas %memsize%
  1103.  
  1104. strings /b16 totalmem = mul %totalmem%, 10
  1105. strings /b16 totalmem = convert %totalmem%, A
  1106. strings /u totalmem = addcommas %totalmem%
  1107.  
  1108. echo  %totalmem% bytes total conventional memory
  1109. echo  %memsize% largest program executable size
  1110. echo.
  1111. rem
  1112. rem Done, clean up all vars
  1113. rem
  1114. set llseg=
  1115. set lloff=
  1116. set memseg=
  1117. set memowner=
  1118. set memsize=
  1119. set memtype=
  1120. set memname=
  1121. set memtemp=
  1122. set freemem=
  1123. set totalmem=
  1124. set diff=
  1125.  
  1126. Figure 5: BATMEM.BAT produces a list of the DOS memory segments.
  1127. ------------------------------------------------------------------------